package com.gxa.community.admin.advice;


import com.gxa.community.admin.mapper.system.LogMapper;
import com.gxa.community.core.pojo.domain.OperationLog;
import com.gxa.community.core.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * @author bill
 * @date 2022/7/8 14:28
 */
@Component
@Aspect
@Slf4j
public class ControllerLogAspect {

    @Autowired
    private LogMapper logMapper;//日志 mapper

    private HttpServletRequest request = null;//请求
    private long operationTime = 0; // 开始时间,即操作时间
    private String loginAct = null; // 操作人
    private String ip = null;//ip
    private String name = null;//操作行为


    //FIXME 需要将AOP完善, 记录业务异常
    @Pointcut("@annotation(com.gxa.community.admin.advice.Log)")
    public void pointCut(){}

    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint) throws ClassNotFoundException {
        //获取注解内容
        Log log1 = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(Log.class);
        String action = log1.action();
        String title = log1.title();
        System.out.println(action+title);
        //记录操作行为、操作时间、操作人、ip
        name = action;
        operationTime = System.currentTimeMillis();
        loginAct = "admin";
        request = this.getHttpServletRequest();
        ip = getIp();
        log.info("name:{}===operationTime:{}===loginAct:{}===ip:{}",name,operationTime,loginAct,ip);



        //TODO 获取当前用户的信息: 从请求头中的jwtToken中获取
        // 判断是否为空, 防止用户信息为空导致空指针
//        if(!StringUtils.isEmpty(UserThreadLocal.get())){
//            log.info("操作人信息:{}",UserThreadLocal.get().toString());
//        }


    }


    @AfterReturning(pointcut = "pointCut()",returning = "result")
    public void afterReturn(Object result){
        R r = (R)result;
        Integer code = (Integer) r.get("code");
        log.info("执行结果:{}", code);
        //如果操作成功，即code==200,就往数据库的操作记录表写数据
        if(code == 200){
            OperationLog operationLog = new OperationLog();
            operationLog.setOperationTime(operationTime);
            operationLog.setIp(ip);
            operationLog.setName(name);
            operationLog.setLoginAct(loginAct);
            logMapper.insert(operationLog);
        }
        log.info("=======执行完毕=======");
    }


    /**
     * @Description: 获取request
     */
    public HttpServletRequest getHttpServletRequest(){
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes)ra;
        HttpServletRequest request = sra.getRequest();
        return request;
    }

    public String getIp() {
        String ip = this.request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = this.request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = this.request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = this.request.getRemoteAddr();
        }
        return ip;
    }
}
